﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge;
using AForge.Math.Geometry;

using Bildverarbeitung;




namespace Bildverarbeitung.CGFilter
{
    public class KraftMatthiasFilter : Bildverarbeitung.IFilter
    {


        //return Namen
        public String GetName()
        {
            return ("KraftMatthias");
        }


        public Bitmap GetImageWithDoor(Bitmap quellepic)
        {
            if (quellepic != null)
            {
                float groesstesRechteck = 0;
                
                Bitmap filterbild;
                Bitmap readimage;

                Pen rot = new Pen(Color.Red, 4);
                Pen gruen = new Pen(Color.Green, 4);

                
                SaturationCorrection sfilter = new SaturationCorrection(-0.8f);

              

                readimage = AForge.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply(quellepic);
                
                // Filter erstellen
                AForge.Imaging.Filters.SobelEdgeDetector edgeFilter = new AForge.Imaging.Filters.SobelEdgeDetector();
                edgeFilter.ApplyInPlace(readimage);
                filterbild = readimage.Clone(new Rectangle(0, 0, readimage.Width, readimage.Height), PixelFormat.Format24bppRgb);
                List<List<IntPoint>> rechtecke = shapeChecker(filterbild);

                
                filterbild = quellepic;
                sfilter.ApplyInPlace(filterbild);

                List<IntPoint> groesstesRechteckEcken = null;

                Graphics grafikscene = Graphics.FromImage(filterbild);
               
                foreach (List<IntPoint> eckpunkte in rechtecke)
                {
                    if (eckpunkte.Count == 4)
                    { 
                        // Bereich des groessten Rechtecks
                        if (kalkulationFlaechen(eckpunkte) > groesstesRechteck)
                        {
                            groesstesRechteck = kalkulationFlaechen(eckpunkte);
                            groesstesRechteckEcken = eckpunkte;
                        }
                        foreach (IntPoint point in eckpunkte)
                        {
                            // zeichne Eckpunkte
                            grafikscene.DrawRectangle(rot, point.X - 2, point.Y - 2, 5, 5);
                        }
                       
                        // zeichne Grenzen
                        grafikscene.DrawPolygon(gruen, ToPointsArray(eckpunkte));
                    }
                }

               
                if (groesstesRechteckEcken != null)
                {
                    SolidBrush gelb = new SolidBrush(Color.Yellow);
                    grafikscene.FillPolygon(gelb, ToPointsArray(groesstesRechteckEcken));
                    gelb.Dispose();
                }

                gruen.Dispose();
                rot.Dispose();
                grafikscene.Dispose();

             
                return filterbild;

            }
            return null;
        }


        private float kalkulationFlaechen(List<IntPoint> ecken)
        {
            // Initialisierung
            float flaeche = 0;
            float halbeFlaeche = 0;
            int counter;


            for (int i = 0; i < ecken.Count; i++)
            {
                counter = (i + 1) % (ecken.Count);
                flaeche += (ecken[i].Y + ecken[counter].Y) * (ecken[i].X - ecken[counter].X);
            }

            halbeFlaeche = flaeche / 2;
            return halbeFlaeche;
        }



        private List<List<IntPoint>> shapeChecker(Bitmap bitmap)
        {
            List<List<IntPoint>> rechteckEcken = new List<List<IntPoint>>();
            
            BitmapData imagebitmap = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite, bitmap.PixelFormat);

            //Farbe ändern
            ColorFiltering cfilter = new ColorFiltering();
            cfilter.Red = new IntRange(0, 64);
            cfilter.Green = new IntRange(0, 64);
            cfilter.Blue = new IntRange(0, 64);
            cfilter.FillOutsideRange = false;
            cfilter.ApplyInPlace(imagebitmap);

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = 5;
            blobCounter.MinWidth = 5;
            blobCounter.ProcessImage(imagebitmap);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(imagebitmap);
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();


            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> ecken;
                shapeChecker.IsConvexPolygon(edgePoints, out ecken);
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(ecken);
                        rechteckEcken.Add(ecken);   
            }
            return rechteckEcken;
        }



        private System.Drawing.Point[] ToPointsArray(List<IntPoint> zeichnePkt)
        {
            System.Drawing.Point[] punkteSpeicher = new System.Drawing.Point[zeichnePkt.Count];

            for (int i = 0, n = zeichnePkt.Count; i < n; i++)
            {
                punkteSpeicher[i] = new System.Drawing.Point(zeichnePkt[i].X, zeichnePkt[i].Y);
            }
            return punkteSpeicher;
        }
    }



}

